package com.ren.fileuploadanddownload.controller;


import com.ren.fileuploadanddownload.entity.User;
import com.ren.fileuploadanddownload.entity.UserFile;
import com.ren.fileuploadanddownload.service.UserFileService;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Controller
@RequestMapping("file")
public class FileController {
    @Autowired
    private UserFileService userFileService;

    //查询所有文件列表，并展示
    @GetMapping("showAll")
    public String findAll(HttpSession session, Model model){
        //在登录的session中获取用户的id
        User user = (User) session.getAttribute("user");
        //根据用户id查询所有的文件信息
        List<UserFile> userFiles = userFileService.findByUserId(user.getId());
        //存入作用域中
        model.addAttribute("files",userFiles);
        return "showAll";
    }
    /*----------------------------------------------------------------------------------*/
    //上传文件
    @PostMapping("upload")
    public String upload(MultipartFile choice, HttpServletRequest request,HttpSession session) throws IOException {
        //1. 文件上传,拿到上传文件的相关信息文件
            //获取文件用户的id
            User user = (User) session.getAttribute("user");
            //获取文件的原始名称
            String oldFileName=choice.getOriginalFilename();
            //获取文件后缀
            String extension = "."+FilenameUtils.getExtension(choice.getOriginalFilename());
            //自定义文件名前缀
            String newFileNamePrefix=new SimpleDateFormat("yyyyMMdd").format(new Date())+ UUID.randomUUID().toString();
            //前后缀去拼接，生成新文件名
            String newFileName = newFileNamePrefix+extension;
            //获取文件大小
            long size=choice.getSize();
            //获取文件类型
            String type=choice.getContentType();

        //2. 处理文件上传:
            // 2.1:自定义存放上传文件的files文件夹的位置，在static目录下
            String realPath = ResourceUtils.getURL("classpath:").getPath() + "static/files";
            //2.2日期目录创建，也就是在files目录下，再以当日日期为文件名创建一个文件夹，不同日上传的文件存放在对应日期的文件夹中
            String dateFormat=new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String dateDirPath = realPath+"/"+dateFormat;
            System.out.println(realPath);
            File dir = new File(dateDirPath);
            //2.3 做判断，如果路径不存在，则创建路径，存在就照常上传
            if (!dir.exists()){
                dir.mkdirs();
            }
            //2.4文件上传
            choice.transferTo(new File(dir,newFileName));

       //3.将文件信息保存数据库
            UserFile userFile = new UserFile();

            userFile.setOldFileName(oldFileName).setNewFileName(newFileName).setExt(extension).setSize(String.valueOf(size))
                    .setType(type).setPath("/files/"+dateFormat).setUserId(user.getId());
            userFileService.save(userFile);

        return "redirect:/file/showAll";
    }
    /*----------------------------------------------------------------------------------*/
    //文件下载
    @GetMapping("download")
    public void download(String id, String OnlineOpen,HttpServletResponse response)throws IOException{
        //获取文件信息
        UserFile userFile=userFileService.findByFileId(id);
        //Detail在线打开其实就是下载的一种方式(在线查看),所以可以在前端传一个自定义的String 的OnlineOpen,
        // 并在前端中：是查看detail就将inline作为值赋值给OnlineOpen传过来,是文件下载就给OnlineOpen赋空值(不传参)传过来，再通过下面的判断完成下载方式的切换，从而实现在线查看和下载
        OnlineOpen= OnlineOpen==null?"attachment":OnlineOpen;
        //只有下载才更新下载次数，在线打开不更新
        if ("attachment".equals(OnlineOpen)){
            userFile.setDowncounts(userFile.getDowncounts()+1);
            userFileService.update(userFile);
        }
        //根据文件名去指定的目录中查找文件
        String realpath = ResourceUtils.getURL("classpath:").getPath() + "/static" + userFile.getPath();
        //读取文件，获取文件输入流
        FileInputStream is = new FileInputStream(new File(realpath, userFile.getNewFileName()));
        //附件下载
        response.setHeader("content-disposition", OnlineOpen+";fileName="+ URLEncoder.encode(userFile.getOldFileName(), "UTF-8"));
        //获取响应输出流
        ServletOutputStream os = response.getOutputStream();
        //文件拷贝
        IOUtils.copy(is,os);
        IOUtils.closeQuietly(is);
        IOUtils.closeQuietly(os);
    }
    /*----------------------------------------------------------------------------------*/
    //删除上传的文件和数据库中的文件信息
    @GetMapping("delete")
    public String deleteinfo(String id) throws FileNotFoundException {
        //根据id查询文件信息
        UserFile userFile=userFileService.findByFileId(id);
        //删除文件
        String realpath = ResourceUtils.getURL("classpath:").getPath() + "/static" + userFile.getPath();
        File file = new File(realpath, userFile.getNewFileName());
        if (file.exists()){
            file.delete();//立即删除
        }
        //删除数据库中的文件信息
        userFileService.delete(id);
        return "redirect:/file/showAll";
    }
    /*----------------------------------------------------------------------------------*/
    //返回当前用户的所有文件列表-----json格式数据
    @GetMapping("findAllJSON")
    @ResponseBody
    public List<UserFile> findAllJSON(HttpSession session,Model model){
        //在登录的session中获取用户的id
        User user = (User) session.getAttribute("user");
        //根据用户id查询所有的文件信息
        List<UserFile> userFiles = userFileService.findByUserId(user.getId());
        return userFiles;
    }
}
